home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PRINTER / JPSRC11.ARJ / JETFONT.C < prev    next >
C/C++ Source or Header  |  1991-08-03  |  21KB  |  674 lines

  1. /*
  2.  *      JET PAK - HP DeskJet and LaserJet series printer utilities
  3.  *
  4.  *      JETFONT module - soft font utility functions
  5.  *
  6.  *      Version 1.1 (Public Domain)
  7.  */
  8.  
  9. /* system include files */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. /* application include files */
  15. #include "jetfont.h"
  16. #include "jetutil.h"
  17.  
  18. /*
  19.  * LOCAL DEFINITIONS
  20.  */
  21.  
  22. /* macros for byte/word i/o */
  23. #define byte_read(nb,fp,dst)                            \
  24.             if (do_byte_read(&nb, fp, &dst) == ERROR)   \
  25.                 return(ERROR);
  26.  
  27. #define int_read(nb,fp,dst)                            \
  28.             if (do_int_read(&nb, fp, &dst) == ERROR)   \
  29.                 return(ERROR);
  30.  
  31. #define byte_write(fp,src)                              \
  32.             if (do_byte_write(fp, src) == ERROR)        \
  33.                 return(ERROR);
  34.  
  35. #define int_write(fp,src)                              \
  36.             if (do_int_write(fp, src) == ERROR)        \
  37.                 return(ERROR);
  38.  
  39. /* Descriptor readers and writers */
  40. static int font_descriptor_read();
  41. static int character_code_read();
  42. static int character_descriptor_read();
  43. static int font_descriptor_write();
  44. static int character_code_write();
  45. static int character_descriptor_write();
  46.  
  47. /* Low level readers and writers */
  48. static int do_byte_read();
  49. static int do_int_read();
  50. static int do_byte_write();
  51. static int do_int_write();
  52.  
  53. /* Command -> handler function mapping table */
  54. static struct {
  55.     int type;
  56.     char *start;
  57.     char *end;
  58.     int (*reader)();
  59.     int (*writer)();
  60. } command_table[] = {
  61.     { FDC,FDC_S,FDC_E,font_descriptor_read,font_descriptor_write },
  62.     { CCC,CCC_S,CCC_E,character_code_read,character_code_write },
  63.     { CDC,CDC_S,CDC_E,character_descriptor_read,character_descriptor_write },
  64. };
  65.  
  66. /*
  67.  * FONT COMMAND I/O
  68.  */
  69.  
  70. int font_command_read(infp, fcp)
  71. FILE *infp;
  72. FONT_COMMAND *fcp;
  73. {
  74.     /*
  75.      * Read an arbitrary font command from infp. Any characters up to
  76.      * the first ESC are silently consumed. If a command is recognised
  77.      * a lower level handler is called to read in the descriptor. If
  78.      * an unrecognised command is encountered, a warning is given.
  79.      */
  80.     int r, i;
  81.     char esc_start[11], esc_end[2];
  82.     int (*reader)();    /* for brain-damaged compilers */
  83.  
  84.     do
  85.     {
  86.         /* skip junk between escape sequences (eg NULs are occasionally
  87.            found in badly constructed fonts) */
  88.         do
  89.         {
  90.             if ((r = getc(infp)) == EOF)
  91.                 return(EOF);
  92.         } while (r != '\033');
  93.  
  94.         /* read a PCL style escape sequence */
  95.         if ((r = fscanf(infp, "%10[^+-0123456789]%d%1s",
  96.                                 esc_start, &fcp->number, esc_end)) == 3)
  97.         {
  98.             for (i = 0; i < sizeofarray(command_table); i++)
  99.             {
  100.                 if (    (strcmp(esc_start, command_table[i].start) == 0)
  101.                      && (strcmp(esc_end  , command_table[i].end  ) == 0) )
  102.                 {
  103.                     fcp->command_type = command_table[i].type;
  104.                     reader = command_table[i].reader;
  105.                     r = (*reader)(infp, fcp);
  106.  
  107.                     /* normal return point */
  108.                     return(r);
  109.                 }
  110.             }
  111.  
  112.             /* this is needed because a few soft fonts include arbitrary
  113.                printer escape sequences that aren't really part of the soft
  114.                font (eg OE18R#US.SFP and SC18R#US.SFP) */
  115.             fprintf(stderr, WARNING_COMMAND_SKIPPED, os_dir, os_file,
  116.                                         esc_start, fcp->number, esc_end);
  117.         }
  118.     } while (r == 3);
  119.  
  120.     /* EOF (normally) or unexpected printer escape sequence structure */
  121.     if (r != EOF)
  122.         r = ERROR;
  123.  
  124.     return(r);
  125. }
  126. int font_command_write(outfp, fcp)
  127. FILE *outfp;
  128. FONT_COMMAND *fcp;
  129. {
  130.     /*
  131.      * Write an arbitrary font command to outfp. The generic part of
  132.      * the escape sequence is output first. Then a lower level handler
  133.      * is called to output the remainder of the escape sequence, which
  134.      * is specific to the actual command.
  135.      */
  136.     int r, i;
  137.     int (*writer)();    /* for brain-damaged compilers */
  138.  
  139.     for (i = 0; i < sizeofarray(command_table); i++)
  140.     {
  141.         if (fcp->command_type == command_table[i].type)
  142.         {
  143.             if ((r = fprintf(outfp, "\033%s%d%1s", command_table[i].start,
  144.                           fcp->number, command_table[i].end)) > 0)
  145.             {
  146.                 writer = command_table[i].writer;
  147.                 r = (*writer)(outfp, fcp);
  148.             }
  149.             else
  150.             {
  151.                 r = ERROR;
  152.             }
  153.  
  154.             break;
  155.         }
  156.     }
  157.  
  158.     return(r);
  159. }
  160.  
  161. static int font_descriptor_read(infp, fcp)
  162. FILE *infp;
  163. FONT_COMMAND *fcp;
  164. {
  165.     /*
  166.      * Read a font descriptor. This is a fairly complicated as there
  167.      * are several data sizes to deal with: the routine is passed an
  168.      * overall data size read in as part of the command. The
  169.      * descriptor(s) themselves include another data size.
  170.      *
  171.      * The difference between the command data size(s) and the sum of
  172.      * the descriptor sizes is accounted for by comment bytes.
  173.      * Although the kosher descriptor size for an LJ soft font is 64,
  174.      * many fonts put in a lower value.
  175.      */
  176.     int i, nc = 0, nd = fcp->number;
  177.     UNSIGNEDBYTE temp_byte;
  178.     char junk;
  179.  
  180.     int_read(nd, infp, fcp->data.font.size);
  181.  
  182.     /* split byte count into data bytes and other bytes */
  183.     if (fcp->data.font.size < 2)
  184.     {
  185.         /* this should never occur in practice */
  186.         nc = nd;
  187.         nd = 0;
  188.     }
  189.     else if (fcp->data.font.size < (nd + 2))
  190.     {
  191.         nc = (nd + 2) - fcp->data.font.size;
  192.         nd -= nc;
  193.     }
  194.  
  195.     byte_read(nd, infp, fcp->data.font.header_format);
  196.     byte_read(nd, infp, fcp->data.font.type);
  197.  
  198.     int_read(nd, infp, fcp->data.font.reserved1);
  199.     int_read(nd, infp, fcp->data.font.baseline_distance);
  200.     int_read(nd, infp, fcp->data.font.cell_width);
  201.     int_read(nd, infp, fcp->data.font.cell_height);
  202.  
  203.     byte_read(nd, infp, fcp->data.font.orientation);
  204.     byte_read(nd, infp, fcp->data.font.spacing);
  205.  
  206.     int_read(nd, infp, fcp->data.font.symbol_set);
  207.     int_read(nd, infp, fcp->data.font.pitch);
  208.     int_read(nd, infp, fcp->data.font.height);
  209.     int_read(nd, infp, fcp->data.font.x_height);
  210.  
  211.     byte_read(nd, infp, fcp->data.font.width_type);
  212.     if (fcp->data.font.header_format == DJ500FONTFORMAT)
  213.     {
  214.         int_read(nd, infp, fcp->data.font.style);
  215.     }
  216.     else
  217.     {
  218.         byte_read(nd, infp, temp_byte);
  219.         fcp->data.font.style = (UNSIGNEDINT)temp_byte;
  220.     }
  221.     byte_read(nd, infp, fcp->data.font.stroke_weight);
  222.     if (fcp->data.font.header_format == DJ500FONTFORMAT)
  223.     {
  224.         int_read(nd, infp, fcp->data.font.typeface);
  225.     }
  226.     else
  227.     {
  228.         byte_read(nd, infp, temp_byte);
  229.         fcp->data.font.typeface = (UNSIGNEDINT)temp_byte;
  230.     }
  231.     byte_read(nd, infp, fcp->data.font.slant);
  232.     byte_read(nd, infp, fcp->data.font.serif_style);
  233.     byte_read(nd, infp, fcp->data.font.quality);
  234.     byte_read(nd, infp, fcp->data.font.placement);
  235.     byte_read(nd, infp, fcp->data.font.underline_distance);
  236.     byte_read(nd, infp, fcp->data.font.underline_height);
  237.  
  238.     int_read(nd, infp, fcp->data.font.text_height);
  239.     int_read(nd, infp, fcp->data.font.text_width);
  240.     int_read(nd, infp, fcp->data.font.first_code);
  241.     int_read(nd, infp, fcp->data.font.last_code);
  242.  
  243.     byte_read(nd, infp, fcp->data.font.pitch_extended);
  244.     byte_read(nd, infp, fcp->data.font.height_extended);
  245.  
  246.     int_read(nd, infp, fcp->data.font.reserved2);
  247.     int_read(nd, infp, fcp->data.font.font_number_top);
  248.     int_read(nd, infp, fcp->data.font.font_number_bot);
  249.  
  250.     for (i = 0; i < sizeof(fcp->data.font.name); i++)
  251.     {
  252.         byte_read(nd, infp, fcp->data.font.name[i]);
  253.         if (fcp->data.font.name[i] == '\0')
  254.             fcp->data.font.name[i] = ' ';
  255.     }
  256.  
  257.     /* this is the DJ specific stuff in the standard header */
  258.     int_read(nd, infp, fcp->data.font.h_pixel_resolution);
  259.     int_read(nd, infp, fcp->data.font.v_pixel_resolution);
  260.  
  261.     byte_read(nd, infp, fcp->data.font.tdu_distance);
  262.     byte_read(nd, infp, fcp->data.font.tdu_height);
  263.     byte_read(nd, infp, fcp->data.font.bdu_distance);
  264.     byte_read(nd, infp, fcp->data.font.bdu_height);
  265.  
  266.     /* read a printer specific block: this is usually present in
  267.        DJ soft fonts but not in any of the LJ soft fonts I have seen.
  268.        This test gets around the problem that many LJ fonts will often
  269.        have a garbage value (ie comment stuff) where you should get a
  270.        descriptor size. If all the data up to the printer specific
  271.        block is present, chances are it's OK to go ahead and
  272.        try to read a printer specific block */
  273.     if (fcp->data.font.size >= DJFDSIZE)
  274.     {
  275.         /* lump byte counts together again */
  276.         nd += nc;
  277.         nc = 0;
  278.  
  279.         int_read(nd, infp, fcp->data.font.specific_size);
  280.  
  281.         /* split byte count into data bytes and other bytes */
  282.         if (fcp->data.font.specific_size < 2)
  283.         {
  284.             /* this does occur - the fonts in Elfring Soft Fonts'
  285.                DJETFONT.ZIP package have a printer specific block
  286.                size of 0 */
  287.             nc = nd;
  288.             nd = 0;
  289.         }
  290.         else if (fcp->data.font.specific_size < (nd + 2))
  291.         {
  292.             nc = (nd + 2) - fcp->data.font.specific_size;
  293.             nd -= nc;
  294.         }
  295.  
  296.         int_read(nd, infp, fcp->data.font.data_size);
  297.         
  298.         byte_read(nd, infp, fcp->data.font.unidirection);
  299.         byte_read(nd, infp, fcp->data.font.compressed);
  300.         byte_read(nd, infp, fcp->data.font.hold_time_factor);
  301.         byte_read(nd, infp, fcp->data.font.no_half_pitch);
  302.         byte_read(nd, infp, fcp->data.font.no_double_pitch);
  303.         byte_read(nd, infp, fcp->data.font.no_half_height);
  304.         byte_read(nd, infp, fcp->data.font.no_bold);
  305.         byte_read(nd, infp, fcp->data.font.no_draft);
  306.         byte_read(nd, infp, fcp->data.font.bold_method);
  307.         byte_read(nd, infp, fcp->data.font.reserved3);
  308.  
  309.         int_read(nd, infp, fcp->data.font.baseline_offset_2);
  310.         int_read(nd, infp, fcp->data.font.baseline_offset_3);
  311.         int_read(nd, infp, fcp->data.font.baseline_offset_4);
  312.  
  313.         if (fcp->data.font.specific_size >= DJ500SSIZE)
  314.         {
  315.             for (i = 0; i < sizeof(fcp->data.font.name_extension); i++)
  316.             {
  317.                 byte_read(nd, infp, fcp->data.font.name_extension[i]);
  318.                 if (fcp->data.font.name_extension[i] == '\0')
  319.                     fcp->data.font.name_extension[i] = ' ';
  320.             }
  321.         }
  322.     }
  323.  
  324.     /* any remaining bytes are comments */
  325.     for (i = 0; i < COMMENT_SIZE_MAX-1 && nc > 0; i++)
  326.     {
  327.         byte_read(nc, infp, fcp->data.font.comment[i]);
  328.         if (fcp->data.font.comment[i] == '\0')
  329.             fcp->data.font.comment[i] = ' ';
  330.     }
  331.     fcp->data.font.comment[i] = '\0';
  332.  
  333.     /* if nc > 0 here, you ran out of space in the comment string */
  334.     while (nc > 0)
  335.         byte_read(nc, infp, junk);
  336.  
  337.     return(OK);
  338. }
  339. static int font_descriptor_write(outfp, fcp)
  340. FILE *outfp;
  341. FONT_COMMAND *fcp;
  342. {
  343.     /*
  344.      * Write a font descriptor. Compared to reading one, this is a
  345.      * cinch.
  346.      */
  347.     int i, len;
  348.  
  349.     int_write(outfp, fcp->data.font.size);
  350.  
  351.     byte_write(outfp, fcp->data.font.header_format);
  352.     byte_write(outfp, fcp->data.font.type);
  353.  
  354.     int_write(outfp, fcp->data.font.reserved1);
  355.     int_write(outfp, fcp->data.font.baseline_distance);
  356.     int_write(outfp, fcp->data.font.cell_width);
  357.     int_write(outfp, fcp->data.font.cell_height);
  358.  
  359.     byte_write(outfp, fcp->data.font.orientation);
  360.     byte_write(outfp, fcp->data.font.spacing);
  361.  
  362.     int_write(outfp, fcp->data.font.symbol_set);
  363.     int_write(outfp, fcp->data.font.pitch);
  364.     int_write(outfp, fcp->data.font.height);
  365.     int_write(outfp, fcp->data.font.x_height);
  366.  
  367.     byte_write(outfp, fcp->data.font.width_type);
  368.     if (fcp->data.font.header_format == DJ500FONTFORMAT)
  369.     {
  370.         int_write(outfp, fcp->data.font.style);
  371.     }
  372.     else
  373.     {
  374.         byte_write(outfp, (UNSIGNEDBYTE)fcp->data.font.style);
  375.     }
  376.     byte_write(outfp, fcp->data.font.stroke_weight);
  377.     if (fcp->data.font.header_format == DJ500FONTFORMAT)
  378.     {
  379.         int_write(outfp, fcp->data.font.typeface);
  380.     }
  381.     else
  382.     {
  383.         byte_write(outfp, (UNSIGNEDBYTE)fcp->data.font.typeface);
  384.     }
  385.     byte_write(outfp, fcp->data.font.slant);
  386.     byte_write(outfp, fcp->data.font.serif_style);
  387.     byte_write(outfp, fcp->data.font.quality);
  388.     byte_write(outfp, fcp->data.font.placement);
  389.     byte_write(outfp, fcp->data.font.underline_distance);
  390.     byte_write(outfp, fcp->data.font.underline_height);
  391.                                                  
  392.     int_write(outfp, fcp->data.font.text_height);
  393.     int_write(outfp, fcp->data.font.text_width);
  394.     int_write(outfp, fcp->data.font.first_code);
  395.     int_write(outfp, fcp->data.font.last_code);
  396.  
  397.     byte_write(outfp, fcp->data.font.pitch_extended);
  398.     byte_write(outfp, fcp->data.font.height_extended);
  399.  
  400.     int_write(outfp, fcp->data.font.reserved2);
  401.     int_write(outfp, fcp->data.font.font_number_top);
  402.     int_write(outfp, fcp->data.font.font_number_bot);
  403.  
  404.     for (i = 0; i < sizeof(fcp->data.font.name); i++)
  405.         byte_write(outfp, fcp->data.font.name[i]);
  406.  
  407.     if (fcp->data.font.size >= DJFDSIZE)
  408.     {
  409.         int_write(outfp, fcp->data.font.h_pixel_resolution);
  410.         int_write(outfp, fcp->data.font.v_pixel_resolution);
  411.  
  412.         byte_write(outfp, fcp->data.font.tdu_distance);
  413.         byte_write(outfp, fcp->data.font.tdu_height);
  414.         byte_write(outfp, fcp->data.font.bdu_distance);
  415.         byte_write(outfp, fcp->data.font.bdu_height);
  416.  
  417.         int_write(outfp, fcp->data.font.specific_size);
  418.         int_write(outfp, fcp->data.font.data_size);
  419.         
  420.         byte_write(outfp, fcp->data.font.unidirection);
  421.         byte_write(outfp, fcp->data.font.compressed);
  422.         byte_write(outfp, fcp->data.font.hold_time_factor);
  423.         byte_write(outfp, fcp->data.font.no_half_pitch);
  424.         byte_write(outfp, fcp->data.font.no_double_pitch);
  425.         byte_write(outfp, fcp->data.font.no_half_height);
  426.         byte_write(outfp, fcp->data.font.no_bold);
  427.         byte_write(outfp, fcp->data.font.no_draft);
  428.         byte_write(outfp, fcp->data.font.bold_method);
  429.         byte_write(outfp, fcp->data.font.reserved3);
  430.  
  431.         int_write(outfp, fcp->data.font.baseline_offset_2);
  432.         int_write(outfp, fcp->data.font.baseline_offset_3);
  433.         int_write(outfp, fcp->data.font.baseline_offset_4);
  434.  
  435.         if (fcp->data.font.specific_size >= DJ500SSIZE)
  436.         {
  437.             for (i = 0; i < sizeof(fcp->data.font.name_extension); i++)
  438.                 byte_write(outfp, fcp->data.font.name_extension[i]);
  439.         }
  440.     }
  441.  
  442.     if ((len = strlen(fcp->data.font.comment)) > 0)
  443.         if (fwrite(fcp->data.font.comment, 1, len, outfp) != len)
  444.             return(ERROR);
  445.  
  446.     return(OK);
  447. }
  448.  
  449. static int character_code_read(infp, fcp)
  450. FILE *infp;
  451. FONT_COMMAND *fcp;
  452. {
  453.     /*
  454.      * Nothing to do here as the character code command doesn't have
  455.      * an associated descriptor
  456.      */
  457.     return(OK);
  458. }
  459. static int character_code_write(outfp, fcp)
  460. FILE *outfp;
  461. FONT_COMMAND *fcp;
  462. {
  463.     /*
  464.      * Nothing to do here as the character code command doesn't have
  465.      * an associated descriptor
  466.      */
  467.     return(OK);
  468. }
  469.  
  470. static int character_descriptor_read(infp, fcp)
  471. FILE *infp;
  472. FONT_COMMAND *fcp;
  473. {
  474.     /*
  475.      * Read a character descriptor. Fortunately character descriptors
  476.      * don't seem to have comments. Half-way through reading the
  477.      * descriptor you discover which kind you're dealing with and
  478.      * switch to different code for each.
  479.      */
  480.     int nd = fcp->number;
  481.     struct ljchar_struct *ljcp;
  482.     struct djchar_struct *djcp;
  483.  
  484.     byte_read(nd, infp, fcp->data.character.format);
  485.     byte_read(nd, infp, fcp->data.character.continuation);
  486.  
  487.     switch(fcp->data.character.format)
  488.     {
  489.     default:
  490.     case LJCHARFORMAT:
  491.         ljcp = &fcp->data.character.data.ljchar;
  492.  
  493.         byte_read(nd, infp, ljcp->descriptor_size);
  494.         byte_read(nd, infp, ljcp->class);
  495.         byte_read(nd, infp, ljcp->orientation);
  496.         byte_read(nd, infp, ljcp->reserved);
  497.  
  498.         int_read(nd, infp, ljcp->left_offset);
  499.         int_read(nd, infp, ljcp->top_offset);
  500.         int_read(nd, infp, ljcp->character_width);
  501.         int_read(nd, infp, ljcp->character_height);
  502.         int_read(nd, infp, ljcp->delta_x);
  503.  
  504.         if (nd > BITMAP_SIZE_MAX)
  505.             return(ERROR);
  506.  
  507.         if (fread(ljcp->bitmap, 1, nd, infp) != nd)
  508.             return(ERROR);
  509.         break;
  510.     case DJCHARFORMAT:
  511.     case DJPCHARFORMAT:
  512.     case DJ500CHARFORMAT:
  513.         djcp = &fcp->data.character.data.djchar;
  514.  
  515.         byte_read(nd, infp, djcp->descriptor_size);
  516.         byte_read(nd, infp, djcp->char_type);
  517.         byte_read(nd, infp, djcp->character_width);
  518.         byte_read(nd, infp, djcp->comp_width);
  519.         byte_read(nd, infp, djcp->left_offset);
  520.         byte_read(nd, infp, djcp->right_offset);
  521.  
  522.         if (nd > BITMAP_SIZE_MAX)
  523.             return(ERROR);
  524.  
  525.         if (fread(djcp->bitmap, 1, nd, infp) != nd)
  526.             return(ERROR);
  527.         break;
  528.     }
  529.  
  530.     return(OK);
  531. }
  532. static int character_descriptor_write(outfp, fcp)
  533. FILE *outfp;
  534. FONT_COMMAND *fcp;
  535. {
  536.     /*
  537.      * Write a character descriptor.
  538.      */
  539.     int nd = fcp->number;
  540.     struct ljchar_struct *ljcp;
  541.     struct djchar_struct *djcp;
  542.  
  543.     byte_write(outfp, fcp->data.character.format);
  544.     byte_write(outfp, fcp->data.character.continuation);
  545.  
  546.     switch(fcp->data.character.format)
  547.     {
  548.     default:
  549.     case LJCHARFORMAT:
  550.         ljcp = &fcp->data.character.data.ljchar;
  551.  
  552.         byte_write(outfp, ljcp->descriptor_size);
  553.         byte_write(outfp, ljcp->class);
  554.         byte_write(outfp, ljcp->orientation);
  555.         byte_write(outfp, ljcp->reserved);
  556.  
  557.         int_write(outfp, ljcp->left_offset);
  558.         int_write(outfp, ljcp->top_offset);
  559.         int_write(outfp, ljcp->character_width);
  560.         int_write(outfp, ljcp->character_height);
  561.         int_write(outfp, ljcp->delta_x);
  562.     
  563.         nd -= (2 + ljcp->descriptor_size);
  564.  
  565.         if (fwrite(ljcp->bitmap, 1, nd, outfp) != nd)
  566.             return(ERROR);
  567.         break;
  568.     case DJCHARFORMAT:
  569.     case DJPCHARFORMAT:
  570.     case DJ500CHARFORMAT:
  571.         djcp = &fcp->data.character.data.djchar;
  572.  
  573.         byte_write(outfp, djcp->descriptor_size);
  574.         byte_write(outfp, djcp->char_type);
  575.         byte_write(outfp, djcp->character_width);
  576.         byte_write(outfp, djcp->comp_width);
  577.         byte_write(outfp, djcp->left_offset);
  578.         byte_write(outfp, djcp->right_offset);
  579.  
  580.         nd -= (2 + djcp->descriptor_size);
  581.  
  582.         if (fwrite(djcp->bitmap, 1, nd, outfp) != nd)
  583.             return(ERROR);
  584.         break;
  585.     }
  586.  
  587.     return(OK);
  588. }
  589.  
  590. /*
  591.  * LOW LEVEL I/O
  592.  */
  593.  
  594. static int do_byte_read(nbp, fp, dp)
  595. int *nbp;
  596. FILE *fp;
  597. UNSIGNEDBYTE *dp;
  598. {
  599.     /*
  600.      * If there's enough data available, read a byte, checking for
  601.      * errors.
  602.      */
  603.     int wrk;
  604.  
  605.     if ((*nbp -=1) < 0)
  606.         *dp = 0;
  607.     else if ((wrk = getc(fp)) == EOF)
  608.         return(ERROR);
  609.     else
  610.         *dp = wrk;
  611.  
  612.     return(OK);
  613. }
  614.  
  615. static int do_int_read(nbp, fp, dp)
  616. int *nbp;
  617. FILE *fp;
  618. UNSIGNEDINT *dp;
  619. {
  620.     /*
  621.      * If there's enough data available, read a word, checking for
  622.      * errors.
  623.      */
  624.     int wrk;
  625.  
  626.     if ((*nbp -= 2) < 0)
  627.         *dp = 0;
  628.     else
  629.     {
  630.         if ((wrk = getc(fp)) == EOF)
  631.             return(ERROR);
  632.  
  633.         *dp = (wrk << 8);
  634.  
  635.         if ((wrk = getc(fp)) == EOF)
  636.             return(ERROR);
  637.  
  638.         *dp |= wrk;
  639.     }
  640.  
  641.     return(OK);
  642. }
  643.  
  644. static int do_byte_write(fp, src)
  645. FILE *fp;
  646. UNSIGNEDBYTE src;
  647. {
  648.     /*
  649.      * Write a byte, checking for errors
  650.      */
  651.  
  652.     if (putc(src, fp) == EOF)
  653.         return(ERROR);
  654.  
  655.     return(OK);
  656. }
  657.  
  658. static int do_int_write(fp, src)
  659. FILE *fp;
  660. UNSIGNEDINT src;
  661. {
  662.     /*
  663.      * Write a word, checking for errors
  664.      */
  665.  
  666.     if (putc(src>>8,fp) == EOF)
  667.         return(ERROR);
  668.  
  669.     if (putc(src&0xff,fp) == EOF)
  670.         return(ERROR);
  671.  
  672.     return(OK);
  673. }
  674.